import tkinter as tk
from tkinter import ttk, filedialog, messagebox, simpledialog
from Crypto.Cipher import AES, DES, DES3, PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Signature import pss
from Crypto.Hash import SHA256, SHA512, MD5
from Crypto import Random
import base64
import string
import hashlib
import json
import os
from datetime import datetime

# =============================================
# 主题配置
# =============================================
class ModernTheme:
    """界面主题颜色配置类"""
    BG_COLOR = "#f5f5f5"      # 背景色
    FG_COLOR = "#333333"      # 前景色(文字颜色)
    BUTTON_BG = "#4CAF50"     # 按钮背景色
    BUTTON_FG = "white"       # 按钮文字颜色
    BUTTON_HOVER = "#45a049"  # 按钮悬停颜色
    ENTRY_BG = "white"        # 输入框背景色
    TEXT_BG = "white"         # 文本框背景色
    FRAME_BG = "#e0e0e0"      # 框架背景色
    LABEL_BG = "#f5f5f5"      # 标签背景色
    ACCENT_COLOR = "#2196F3"  # 强调色
    STATUS_BAR_BG = "#2C3E50" # 状态栏背景色
    STATUS_BAR_FG = "#ECF0F1" # 状态栏文字颜色
    BOTTOM_ACCENT = "#3498DB" # 底部边框颜色
    HISTORY_BG = "#f0f0f0"    # 历史记录背景色
    PROGRESS_BG = "#dddddd"   # 进度条背景色
    PROGRESS_FG = "#4CAF50"   # 进度条前景色
   
# =============================================
# 核心加密算法实现
# =============================================

def aes_encrypt(text, key, mode='ECB', iv=None):
    """
    AES加密算法
    参数:
        text: 要加密的文本
        key: 加密密钥(会自动补全为16/24/32字节)
        mode: 加密模式(ECB或CBC)
        iv: 初始化向量(CBC模式需要)
    返回:
        Base64编码的加密结果(CBC模式包含IV)
    """
    try:
        key = key.encode('utf-8')
        text = text.encode('utf-8')
        
        # 密钥长度处理 (16, 24, 32字节)
        key = key.ljust(32, b'\0')[:32]
        
        # 根据模式创建加密器
        if mode == 'CBC':
            if not iv:
                iv = Random.new().read(AES.block_size)
            cipher = AES.new(key, AES.MODE_CBC, iv)
        else:  # ECB
            cipher = AES.new(key, AES.MODE_ECB)
        
        # PKCS7填充
        pad_len = AES.block_size - (len(text) % AES.block_size)
        text += bytes([pad_len]) * pad_len
        
        encrypted = cipher.encrypt(text)

        if mode == 'CBC':
            return base64.b64encode(iv + encrypted).decode('utf-8')
        return base64.b64encode(encrypted).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"AES加密失败: {str(e)}")
        return ""

def aes_decrypt(encrypted_text, key, mode='ECB'):
    """
    AES解密算法
    参数:
        encrypted_text: Base64编码的加密文本
        key: 解密密钥
        mode: 解密模式(ECB或CBC)
    返回:
        解密后的原始文本
    """
    try:
        key = key.encode('utf-8')
        encrypted_text = base64.b64decode(encrypted_text)
        
        # 密钥长度处理
        key = key.ljust(32, b'\0')[:32]
        
        if mode == 'CBC':
            iv = encrypted_text[:AES.block_size]
            cipher = AES.new(key, AES.MODE_CBC, iv)
            encrypted_text = encrypted_text[AES.block_size:]
        else:
            cipher = AES.new(key, AES.MODE_ECB)
        
        decrypted = cipher.decrypt(encrypted_text)
        
        # PKCS7去除填充
        pad_len = decrypted[-1]
        decrypted = decrypted[:-pad_len]
        
        return decrypted.decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"AES解密失败: {str(e)}")
        return ""

def des_encrypt(text, key, mode='ECB', iv=None):
    """
    DES加密算法
    参数:
        text: 要加密的文本
        key: 加密密钥(会自动补全为8字节)
        mode: 加密模式(ECB或CBC)
        iv: 初始化向量(CBC模式需要)
    返回:
        Base64编码的加密结果(CBC模式包含IV)
    """
    try:
        key = key.encode('utf-8')
        text = text.encode('utf-8')
        
        # 密钥长度处理 (8字节)
        key = key.ljust(8, b'\0')[:8]
        
        if mode == 'CBC':
            if not iv:
                iv = Random.new().read(DES.block_size)
            cipher = DES.new(key, DES.MODE_CBC, iv)
        else:  # ECB
            cipher = DES.new(key, DES.MODE_ECB)
        
        # PKCS7填充
        pad_len = DES.block_size - (len(text) % DES.block_size)
        text += bytes([pad_len]) * pad_len
        
        encrypted = cipher.encrypt(text)
        
        if mode == 'CBC':
            return base64.b64encode(iv + encrypted).decode('utf-8')
        return base64.b64encode(encrypted).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"DES加密失败: {str(e)}")
        return ""

def des_decrypt(encrypted_text, key, mode='ECB'):
    """
    DES解密算法
    参数:
        encrypted_text: Base64编码的加密文本
        key: 解密密钥
        mode: 解密模式(ECB或CBC)
    返回:
        解密后的原始文本
    """
    try:
        key = key.encode('utf-8')
        encrypted_text = base64.b64decode(encrypted_text)
        
        # 密钥长度处理
        key = key.ljust(8, b'\0')[:8]
        
        if mode == 'CBC':
            iv = encrypted_text[:DES.block_size]
            cipher = DES.new(key, DES.MODE_CBC, iv)
            encrypted_text = encrypted_text[DES.block_size:]
        else:
            cipher = DES.new(key, DES.MODE_ECB)
        
        decrypted = cipher.decrypt(encrypted_text)
        
        # PKCS7去除填充
        pad_len = decrypted[-1]
        decrypted = decrypted[:-pad_len]
        
        return decrypted.decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"DES解密失败: {str(e)}")
        return ""

def triple_des_encrypt(text, key, mode='CBC', iv=None):
    """
    3DES加密算法
    参数:
        text: 要加密的文本
        key: 加密密钥(16或24字节)
        mode: 加密模式(ECB或CBC)
        iv: 初始化向量(CBC模式需要)
    返回:
        Base64编码的加密结果(CBC模式包含IV)
    """
    try:
        # 确保密钥长度为16或24字节
        key = key.encode('utf-8')
        if len(key) < 16:
            key = key.ljust(16, b'\0')
        elif 16 < len(key) < 24:
            key = key.ljust(24, b'\0')
        elif len(key) > 24:
            key = key[:24]
        
        if mode == 'CBC':
            if not iv:
                iv = Random.new().read(DES3.block_size)
            cipher = DES3.new(key, DES3.MODE_CBC, iv)
        else:  # ECB
            cipher = DES3.new(key, DES3.MODE_ECB)
        
        # PKCS7填充
        pad_len = DES3.block_size - (len(text) % DES3.block_size)
        text = text.encode('utf-8') + bytes([pad_len]) * pad_len
        
        encrypted = cipher.encrypt(text)
        
        if mode == 'CBC':
            return base64.b64encode(iv + encrypted).decode('utf-8')
        return base64.b64encode(encrypted).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"3DES加密失败: {str(e)}")
        return ""

def triple_des_decrypt(encrypted_text, key, mode='CBC'):
    """
    3DES解密算法
    参数:
        encrypted_text: Base64编码的加密文本
        key: 解密密钥
        mode: 解密模式(ECB或CBC)
    返回:
        解密后的原始文本
    """
    try:
        key = key.encode('utf-8')
        if len(key) < 16:
            key = key.ljust(16, b'\0')
        elif 16 < len(key) < 24:
            key = key.ljust(24, b'\0')
        elif len(key) > 24:
            key = key[:24]
        
        encrypted_text = base64.b64decode(encrypted_text)
        
        if mode == 'CBC':
            iv = encrypted_text[:DES3.block_size]
            cipher = DES3.new(key, DES3.MODE_CBC, iv)
            encrypted_text = encrypted_text[DES3.block_size:]
        else:
            cipher = DES3.new(key, DES3.MODE_ECB)
        
        decrypted = cipher.decrypt(encrypted_text)
        
        # 去除填充
        pad_len = decrypted[-1]
        decrypted = decrypted[:-pad_len]
        
        return decrypted.decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"3DES解密失败: {str(e)}")
        return ""
    
# 在全局变量部分添加RSA密钥存储
rsa_private_key = None
rsa_public_key = None

def generate_rsa_keys():
    """
    生成RSA密钥对
    返回:
        (private_key_pem, public_key_pem) 元组(PEM格式)
    """
    try:
        key = RSA.generate(2048)
        private_key_pem = key.export_key().decode('utf-8')
        public_key_pem = key.publickey().export_key().decode('utf-8')
        return private_key_pem, public_key_pem
    except Exception as e:
        messagebox.showerror("错误", f"生成RSA密钥失败: {str(e)}")
        return None, None

def rsa_encrypt(text, public_key):
    """
    RSA加密算法
    参数:
        text: 要加密的文本
        public_key: RSA公钥
    返回:
        Base64编码的加密结果
    """
    try:
        cipher = PKCS1_OAEP.new(public_key)
        encrypted_text = cipher.encrypt(text.encode('utf-8'))
        return base64.b64encode(encrypted_text).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"RSA加密失败: {str(e)}")
        return ""

def rsa_decrypt(encrypted_text, private_key):
    """
    RSA解密算法
    参数:
        encrypted_text: Base64编码的加密文本
        private_key: RSA私钥
    返回:
        解密后的原始文本
    """
    try:
        encrypted_text = base64.b64decode(encrypted_text)
        cipher = PKCS1_OAEP.new(private_key)
        decrypted_text = cipher.decrypt(encrypted_text).decode('utf-8')
        return decrypted_text
    except Exception as e:
        messagebox.showerror("错误", f"RSA解密失败: {str(e)}")
        return ""

def rsa_sign(text, private_key):
    """
    RSA签名算法
    参数:
        text: 要签名的文本
        private_key: RSA私钥
    返回:
        Base64编码的签名
    """
    try:
        hash_object = SHA256.new(text.encode('utf-8'))
        signer = pss.new(private_key)
        signature = signer.sign(hash_object)
        return base64.b64encode(signature).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"RSA签名失败: {str(e)}")
        return ""

def rsa_verify(text, signature, public_key):
    """
    RSA验证签名
    参数:
        text: 原始文本
        signature: Base64编码的签名
        public_key: RSA公钥
    返回:
        验证结果(True/False)
    """
    try:
        hash_object = SHA256.new(text.encode('utf-8'))
        signature = base64.b64decode(signature)
        verifier = pss.new(public_key)
        verifier.verify(hash_object, signature)
        return True
    except (ValueError, TypeError) as e:
        return False

def compute_hash(text, algorithm='SHA-256'):
    """
    计算文本哈希值
    参数:
        text: 要计算哈希的文本
        algorithm: 哈希算法(SHA-256, SHA-512等)
    返回:
        哈希值的十六进制表示
    """
    try:
        text = text.encode('utf-8')
        if algorithm == 'SHA-256':
            return SHA256.new(text).hexdigest()
        elif algorithm == 'SHA-512':
            return SHA512.new(text).hexdigest()
        elif algorithm == 'MD5':
            return MD5.new(text).hexdigest()
        elif algorithm == 'SHA3-256':
            return hashlib.sha3_256(text).hexdigest()
        elif algorithm == 'SHA3-512':
            return hashlib.sha3_512(text).hexdigest()
        elif algorithm == 'BLAKE2b':
            return hashlib.blake2b(text).hexdigest()
        else:
            return ""
    except Exception as e:
        messagebox.showerror("错误", f"哈希计算失败: {str(e)}")
        return ""

def caesar_encrypt(text, shift):
    """
    凯撒密码加密
    参数:
        text: 要加密的文本
        shift: 位移量
    返回:
        加密后的文本
    """
    try:
        shift = int(shift)
        result = ""
        for char in text:
            if char.isupper():
                result += chr((ord(char) + shift - 65) % 26 + 65)
            elif char.islower():
                result += chr((ord(char) + shift - 97) % 26 + 97)
            else:
                result += char
        return result
    except Exception as e:
        messagebox.showerror("错误", f"凯撒加密失败: {str(e)}")
        return ""

def caesar_decrypt(text, shift):
    """
    凯撒密码解密
    参数:
        text: 要解密的文本
        shift: 位移量
    返回:
        解密后的文本
    """
    try:
        shift = int(shift)
        return caesar_encrypt(text, -shift)
    except Exception as e:
        messagebox.showerror("错误", f"凯撒解密失败: {str(e)}")
        return ""

def vigenere_encrypt(text, key):
    """
    维吉尼亚密码加密
    参数:
        text: 要加密的文本
        key: 密钥字符串
    返回:
        加密后的文本
    """
    try:
        key = key.upper()
        key_length = len(key)
        key_as_int = [ord(i) for i in key]
        text_int = [ord(i) for i in text]
        result = ""
        for i in range(len(text_int)):
            if text[i].isupper():
                value = (text_int[i] + key_as_int[i % key_length] - 130) % 26
                result += chr(value + 65)
            elif text[i].islower():
                value = (text_int[i] + key_as_int[i % key_length] - 194) % 26
                result += chr(value + 97)
            else:
                result += text[i]
        return result
    except Exception as e:
        messagebox.showerror("错误", f"维吉尼亚加密失败: {str(e)}")
        return ""

def vigenere_decrypt(text, key):
    """
    维吉尼亚密码解密
    参数:
        text: 要解密的文本
        key: 密钥字符串
    返回:
        解密后的文本
    """
    try:
        key = key.upper()
        key_length = len(key)
        key_as_int = [ord(i) for i in key]
        text_int = [ord(i) for i in text]
        result = ""
        for i in range(len(text_int)):
            if text[i].isupper():
                value = (text_int[i] - key_as_int[i % key_length] - 130) % 26
                result += chr(value + 65)
            elif text[i].islower():
                value = (text_int[i] - key_as_int[i % key_length] - 194) % 26
                result += chr(value + 97)
            else:
                result += text[i]
        return result
    except Exception as e:
        messagebox.showerror("错误", f"维吉尼亚解密失败: {str(e)}")
        return ""

def base64_encode(text):
    """
    Base64编码
    参数:
        text: 要编码的文本
    返回:
        Base64编码结果
    """
    try:
        return base64.b64encode(text.encode('utf-8')).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"Base64编码失败: {str(e)}")
        return ""

def base64_decode(text):
    """
    Base64解码
    参数:
        text: Base64编码的文本
    返回:
        解码后的原始文本
    """
    try:
        return base64.b64decode(text.encode('utf-8')).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"Base64解码失败: {str(e)}")
        return ""

def rail_fence_encrypt(text, rails):
    """
    栅栏密码加密
    参数:
        text: 要加密的文本
        rails: 栅栏行数
    返回:
        加密后的文本
    """
    try:
        rails = int(rails)
        fence = [[] for _ in range(rails)]
        rail = 0
        direction = 1
        
        for char in text:
            fence[rail].append(char)
            rail += direction
            if rail == rails - 1 or rail == 0:
                direction = -direction
                
        return ''.join([''.join(rail) for rail in fence])
    except Exception as e:
        messagebox.showerror("错误", f"栅栏加密失败: {str(e)}")
        return ""

def rail_fence_decrypt(text, rails):
    """
    栅栏密码解密
    参数:
        text: 要解密的文本
        rails: 栅栏行数
    返回:
        解密后的原始文本
    """
    try:
        rails = int(rails)
        fence = [['' for _ in range(len(text))] for _ in range(rails)]
        rail = 0
        direction = 1
        
        # 标记栅栏位置
        for i in range(len(text)):
            fence[rail][i] = '*'
            rail += direction
            if rail == rails - 1 or rail == 0:
                direction = -direction
                
        # 填充字符
        index = 0
        for i in range(rails):
            for j in range(len(text)):
                if fence[i][j] == '*' and index < len(text):
                    fence[i][j] = text[index]
                    index += 1
                    
        # 读取解密结果
        rail = 0
        direction = 1
        result = []
        for i in range(len(text)):
            result.append(fence[rail][i])
            rail += direction
            if rail == rails - 1 or rail == 0:
                direction = -direction
                
        return ''.join(result)
    except Exception as e:
        messagebox.showerror("错误", f"栅栏解密失败: {str(e)}")
        return ""
    
    # 摩斯密码字典
MORSE_CODE_DICT = {
    'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.',
    'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..',
    'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.',
    'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
    'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--',
    '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..',
    '9': '----.', '0': '-----', ',': '--..--', '.': '.-.-.-', '?': '..--..',
    '/': '-..-.', '-': '-....-', '(': '-.--.', ')': '-.--.-', ' ': '/'
}

# 反转摩斯密码字典用于解密
MORSE_CODE_DICT_REVERSED = {v: k for k, v in MORSE_CODE_DICT.items()}

def morse_encrypt(text):
    """
    摩斯密码加密
    参数:
        text: 要加密的文本(仅支持字母、数字和部分符号)
    返回:
        摩斯密码字符串
    """
    try:
        encrypted = []
        for char in text.upper():
            if char in MORSE_CODE_DICT:
                encrypted.append(MORSE_CODE_DICT[char])
            else:
                raise ValueError(f"不支持的字符: {char}")
        return ' '.join(encrypted)
    except Exception as e:
        messagebox.showerror("错误", f"摩斯加密失败: {str(e)}")
        return ""

def morse_decrypt(text):
    """
    摩斯密码解密
    参数:
        text: 摩斯密码字符串
    返回:
        解密后的原始文本
    """
    try:
        decrypted = []
        for code in text.split(' '):
            if code in MORSE_CODE_DICT_REVERSED:
                decrypted.append(MORSE_CODE_DICT_REVERSED[code])
            else:
                raise ValueError(f"无效的摩斯码: {code}")
        return ''.join(decrypted)
    except Exception as e:
        messagebox.showerror("错误", f"摩斯解密失败: {str(e)}")
        return ""

def ascii_encrypt(text):
    """
    ASCII编码
    参数:
        text: 要编码的文本
    返回:
        ASCII码字符串(空格分隔)
    """
    try:
        # 使用 string 模块确保只处理可打印的字符
        filtered_text = ''.join(filter(lambda x: x in string.printable, text))
        ascii_codes = ' '.join(str(ord(char)) for char in filtered_text)
        return ascii_codes
    except Exception as e:
        messagebox.showerror("错误", f"ASCII编码失败: {str(e)}")
        return ""

def ascii_decrypt(text):
    """
    ASCII解码
    参数:
        text: ASCII码字符串(空格分隔)
    返回:
        解码后的原始文本
    """
    try:
        # 将 ASCII 码字符串分割成单独的数字
        ascii_codes = text.split()
        # 将每个数字转换为对应的字符
        decoded_chars = [chr(int(code)) for code in ascii_codes]
        # 将字符列表组合成字符串
        return ''.join(decoded_chars)
    except Exception as e:
        messagebox.showerror("错误", f"ASCII解码失败: {str(e)}")
        return ""
def rc4_encrypt(text, key):
    """
    RC4加密算法
    参数:
        text: 要加密的文本
        key: 加密密钥
    返回:
        Base64编码的加密结果
    """
    try:
        # RC4算法实现
        S = list(range(256))
        j = 0
        key = key.encode('utf-8')
        
        # KSA (Key-Scheduling Algorithm)
        for i in range(256):
            j = (j + S[i] + key[i % len(key)]) % 256
            S[i], S[j] = S[j], S[i]
        
        # PRGA (Pseudo-Random Generation Algorithm)
        i = j = 0
        encrypted = []
        for char in text.encode('utf-8'):
            i = (i + 1) % 256
            j = (j + S[i]) % 256
            S[i], S[j] = S[j], S[i]
            k = S[(S[i] + S[j]) % 256]
            encrypted.append(char ^ k)
        
        return base64.b64encode(bytes(encrypted)).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"RC4加密失败: {str(e)}")
        return ""

def rc4_decrypt(encrypted_text, key):
    """
    RC4解密算法
    参数:
        encrypted_text: Base64编码的加密文本
        key: 解密密钥
    返回:
        解密后的原始文本
    """
    try:
        encrypted_bytes = base64.b64decode(encrypted_text)
        # RC4算法实现 (加密和解密过程相同)
        S = list(range(256))
        j = 0
        key = key.encode('utf-8')
        
        # KSA (Key-Scheduling Algorithm)
        for i in range(256):
            j = (j + S[i] + key[i % len(key)]) % 256
            S[i], S[j] = S[j], S[i]
        
        # PRGA (Pseudo-Random Generation Algorithm)
        i = j = 0
        decrypted = []
        for char in encrypted_bytes:
            i = (i + 1) % 256
            j = (j + S[i]) % 256
            S[i], S[j] = S[j], S[i]
            k = S[(S[i] + S[j]) % 256]
            decrypted.append(char ^ k)
        
        return bytes(decrypted).decode('utf-8')
    except Exception as e:
        messagebox.showerror("错误", f"RC4解密失败: {str(e)}")
        return ""

# =============================================
# GUI界面和事件处理
# =============================================

# 功能: 操作历史记录
class HistoryManager:
    """管理操作历史记录"""
    HISTORY_FILE = "operation_history.json"
    MAX_HISTORY = 50  # 最大历史记录数
    
    def __init__(self):
        self.history = []
        self.load_history()
    
    def load_history(self):
        """从文件加载历史记录"""
        if os.path.exists(self.HISTORY_FILE):
            try:
                with open(self.HISTORY_FILE, 'r', encoding='utf-8') as f:
                    self.history = json.load(f)
            except:
                self.history = []
    
    def save_history(self):
        """保存历史记录到文件"""
        try:
            with open(self.HISTORY_FILE, 'w', encoding='utf-8') as f:
                json.dump(self.history[-self.MAX_HISTORY:], f, ensure_ascii=False, indent=2)
        except:
            pass
    
    def add_record(self, operation_type, algorithm, text, result):
        """添加新的历史记录"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        record = {
            "timestamp": timestamp,
            "operation": operation_type,
            "algorithm": algorithm,
            "input": text[:100] + "..." if len(text) > 100 else text,
            "result": result[:100] + "..." if len(result) > 100 else result
        }
        self.history.append(record)
        if len(self.history) > self.MAX_HISTORY:
            self.history = self.history[-self.MAX_HISTORY:]
        self.save_history()
    
    def get_history(self):
        """获取所有历史记录"""
        return self.history.copy()
    
    # 创建历史管理器实例
history_manager = HistoryManager()

def generate_rsa_key_pair():
    """生成RSA密钥对并显示在界面"""
    try:
        private_key, public_key = generate_rsa_keys()
        if private_key and public_key:
            # 创建新窗口显示密钥
            key_window = tk.Toplevel(root)
            key_window.title("RSA密钥对")
            key_window.geometry("600x400")

            # 私钥显示
            ttk.Label(key_window, text="私钥 (妥善保存):", font=('Arial', 10, 'bold')).pack(pady=(10, 5))
            private_text = tk.Text(key_window, height=8, width=70, wrap=tk.WORD)
            private_text.insert(tk.END, private_key)
            private_text.pack(padx=10, pady=5)

            # 公钥显示
            ttk.Label(key_window, text="公钥:", font=('Arial', 10, 'bold')).pack(pady=(10, 5))
            public_text = tk.Text(key_window, height=6, width=70, wrap=tk.WORD)
            public_text.insert(tk.END, public_key)
            public_text.pack(padx=10, pady=5)

            # 保存按钮
            save_frame = ttk.Frame(key_window)
            save_frame.pack(pady=10)
            ttk.Button(save_frame,text="保存私钥",command=lambda: save_key_to_file(private_key, key_window)).pack(side=tk.LEFT, padx=5)
            ttk.Button(save_frame,text="保存公钥",command=lambda: save_key_to_file(public_key, key_window)).pack(side=tk.LEFT, padx=5)
           
            # 更新全局密钥变量
            global rsa_private_key, rsa_public_key
            rsa_private_key = RSA.import_key(private_key)
            rsa_public_key = RSA.import_key(public_key)
    except Exception as e:
        messagebox.showerror("错误", f"生成RSA密钥对失败: {str(e)}")

def save_key_to_file(key_content, key_window=None):
    """保存密钥到文件"""
    file_path = filedialog.asksaveasfilename(
        defaultextension=".pem",
        filetypes=[("PEM files", "*.pem"), ("All files", "*.*")]
    )
    if file_path:
        try:
            with open(file_path, 'w') as file:
                file.write(key_content)
            messagebox.showinfo("成功", "密钥已保存")
            # 不关闭窗口，保持打开状态
            if key_window:
                key_window.focus_set()  # 将焦点重新设置到密钥窗口
        except Exception as e:
            messagebox.showerror("错误", f"保存密钥失败: {str(e)}")
            if key_window:
                key_window.focus_set()

def load_rsa_key(is_private=True):
    """从文件加载RSA密钥"""
    file_path = filedialog.askopenfilename(filetypes=[("PEM files", "*.pem"), ("All files", "*.*")])
    if file_path:
        try:
            with open(file_path, 'r') as file:
                key_content = file.read()
                key = RSA.import_key(key_content)
                
                global rsa_private_key, rsa_public_key
                if is_private:
                    rsa_private_key = key
                    messagebox.showinfo("成功", "私钥已加载")
                else:
                    rsa_public_key = key
                    messagebox.showinfo("成功", "公钥已加载")
        except Exception as e:
            messagebox.showerror("错误", f"加载密钥失败: {str(e)}")

def encrypt_text():
    """加密按钮点击事件处理"""
    text = text_entry.get("1.0", tk.END).strip()
    key = key_entry.get()
    algorithm = algorithm_var.get()
    mode = mode_var.get() if algorithm in ["AES", "DES", "3DES"] else ""
    
    if not text:
        messagebox.showwarning("警告", "请输入要加密的文本")
        return
    
    if algorithm in ["AES", "DES", "3DES", "Vigenere", "RC4"] and not key:
        messagebox.showwarning("警告", "请输入密钥")
        return
    
    if algorithm in ["Caesar", "Rail Fence"] and not key.isdigit():
        messagebox.showwarning("警告", "请输入有效的数字密钥")
        return
    
    result = ""
    signature = ""
    
    if algorithm == "AES":
        result = aes_encrypt(text, key, mode)
    elif algorithm == "DES":
        result = des_encrypt(text, key, mode)
    elif algorithm == "3DES":
        result = triple_des_encrypt(text, key, mode)
    elif algorithm == "RSA":
        if not rsa_public_key:
            messagebox.showwarning("警告", "请先生成或加载RSA公钥")
            return
        result = rsa_encrypt(text, rsa_public_key)
        signature = rsa_sign(text, rsa_private_key if rsa_private_key else rsa_public_key)
    elif algorithm == "Caesar":
        result = caesar_encrypt(text, key)
    elif algorithm == "Vigenere":
        result = vigenere_encrypt(text, key)
    elif algorithm == "Base64":
        result = base64_encode(text)
    elif algorithm == "Rail Fence":
        result = rail_fence_encrypt(text, key)
    elif algorithm == "Morse":
        result = morse_encrypt(text)
    elif algorithm == "ASCII":
        result = ascii_encrypt(text)
    elif algorithm == "RC4":
        result = rc4_encrypt(text, key)
    
    result_text.delete("1.0", tk.END)
    result_text.insert(tk.END, result)
    
    if signature:
        signature_label.config(text=f"签名: {signature}")
    else:
        signature_label.config(text="")

    # 添加历史记录
    history_manager.add_record("加密", algorithm, text, result)
    update_status(f"{algorithm}加密完成")

def decrypt_text():
    """解密按钮点击事件处理"""
    text = text_entry.get("1.0", tk.END).strip()
    key = key_entry.get()
    algorithm = algorithm_var.get()
    mode = mode_var.get() if algorithm in ["AES", "DES", "3DES"] else ""
    
    if not text:
        messagebox.showwarning("警告", "请输入要解密的文本")
        return
    
    if algorithm in ["AES", "DES", "3DES", "Vigenere", "RC4"] and not key:
        messagebox.showwarning("警告", "请输入密钥")
        return
    
    if algorithm in ["Caesar", "Rail Fence"] and not key.isdigit():
        messagebox.showwarning("警告", "请输入有效的数字密钥")
        return
    
    result = ""
    
    if algorithm == "AES":
        result = aes_decrypt(text, key, mode)
    elif algorithm == "DES":
        result = des_decrypt(text, key, mode)
    elif algorithm == "3DES":
        result = triple_des_decrypt(text, key, mode)
    elif algorithm == "RSA":
        if not rsa_private_key:
            messagebox.showwarning("警告", "请先生成或加载RSA私钥")
            return
        result = rsa_decrypt(text, rsa_private_key)
    elif algorithm == "Caesar":
        result = caesar_decrypt(text, key)
    elif algorithm == "Vigenere":
        result = vigenere_decrypt(text, key)
    elif algorithm == "Base64":
        result = base64_decode(text)
    elif algorithm == "Rail Fence":
        result = rail_fence_decrypt(text, key)
    elif algorithm == "Morse":
        result = morse_decrypt(text)
    elif algorithm == "ASCII":
        result = ascii_decrypt(text)
    elif algorithm == "RC4":
        result = rc4_decrypt(text, key)
    
    result_text.delete("1.0", tk.END)
    result_text.insert(tk.END, result)
    signature_label.config(text="")

    # 添加历史记录
    history_manager.add_record("解密", algorithm, text, result)
    update_status(f"{algorithm}解密完成")

def compute_hash_text():
    """哈希计算按钮点击事件处理"""
    text = text_entry.get("1.0", tk.END).strip()
    algorithm = hash_algorithm_var.get()
    
    if not text:
        messagebox.showwarning("警告", "请输入要计算哈希的文本")
        return
    
    result = compute_hash(text, algorithm)
    
    result_text.delete("1.0", tk.END)
    result_text.insert(tk.END, result)
    signature_label.config(text="")

    # 添加历史记录
    history_manager.add_record("哈希", algorithm, text, result)
    update_status(f"{algorithm}哈希计算完成")

def clear_text():
    """清空按钮点击事件处理"""
    text_entry.delete("1.0", tk.END)
    key_entry.delete(0, tk.END)
    result_text.delete("1.0", tk.END)
    signature_label.config(text="")

def copy_result():
    """复制结果按钮点击事件处理"""
    result = result_text.get("1.0", tk.END).strip()
    if result:
        root.clipboard_clear()
        root.clipboard_append(result)
        messagebox.showinfo("成功", "结果已复制到剪贴板")
    else:
        messagebox.showwarning("警告", "没有可复制的内容")

def load_from_file():
    """从文件读取按钮点击事件处理"""
    file_path = filedialog.askopenfilename()
    if file_path:
        try:
            with open(file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                text_entry.delete("1.0", tk.END)
                text_entry.insert(tk.END, content)
        except Exception as e:
            messagebox.showerror("错误", f"读取文件失败: {str(e)}")

def save_to_file():
    """保存结果按钮点击事件处理"""
    result = result_text.get("1.0", tk.END).strip()
    if result:
        file_path = filedialog.asksaveasfilename(defaultextension=".txt")
        if file_path:
            try:
                with open(file_path, 'w', encoding='utf-8') as file:
                    file.write(result)
                messagebox.showinfo("成功", "结果已保存到文件")
            except Exception as e:
                messagebox.showerror("错误", f"保存文件失败: {str(e)}")
    else:
        messagebox.showwarning("警告", "没有可保存的内容")

def on_algorithm_selected(event):
    """算法选择变化事件处理"""
    selected_algorithm = algorithm_var.get()
    if selected_algorithm in ["AES", "DES", "3DES"]:
        mode_label.grid()
        mode_menu.grid()
    else:
        mode_label.grid_remove()
        mode_menu.grid_remove()

    if selected_algorithm == 'RSA':
        generate_rsa_button.grid()
        load_private_button.grid()
        load_public_button.grid()
        verify_button.grid()  
    else:
        generate_rsa_button.grid_remove()
        load_private_button.grid_remove()
        load_public_button.grid_remove()
        verify_button.grid_remove()  

# 签名验证功能（RSA）
def verify_signature():
    """验证签名"""
    text = text_entry.get("1.0", tk.END).strip()
    signature = simpledialog.askstring("验证签名", "请输入签名:")
    
    if not text or not signature:
        return
    
    if not rsa_public_key:
        messagebox.showwarning("警告", "请加载RSA公钥")
        return
    
    if rsa_verify(text, signature, rsa_public_key):
        messagebox.showinfo("成功", "签名验证通过!")
        root.clipboard_clear()
        root.clipboard_append(signature)
    else:
        messagebox.showerror("失败", "签名验证失败!")

# 添加右键菜单
def show_context_menu(event):
    menu = tk.Menu(root, tearoff=0)
    menu.add_command(label="复制签名", command=lambda: copy_to_clipboard(signature_label.cget("text").replace("签名: ", "")))
    menu.tk_popup(event.x_root, event.y_root)

# 签名内容复制到剪贴板
def copy_to_clipboard(text):
    if text:
        root.clipboard_clear()
        root.clipboard_append(text)
        messagebox.showinfo("成功", "签名已复制到剪贴板")
    else:
        messagebox.showwarning("警告", "没有可复制的内容")

def on_enter(e):
    """按钮悬停效果 - 鼠标进入"""
    e.widget.configure(style='Hover.TButton')

def on_leave(e):
    """按钮悬停效果 - 鼠标离开"""
    e.widget.configure(style='TButton')

# 功能: 算法说明提示
ALGORITHM_DESCRIPTIONS = {
    "AES": "高级加密标准(AES)，对称加密算法，支持128/192/256位密钥\n\n模式:\n- ECB: 电子密码本模式(简单但不安全)\n- CBC: 密码块链接模式(更安全，需要初始化向量)",
    "DES": "数据加密标准(DES)，对称加密算法，使用56位密钥\n\n注意: 已不再安全，仅用于学习目的",
    "3DES": "三重DES，比DES更安全但速度较慢\n\n支持16或24字节密钥",
    "RSA": "非对称加密算法，用于加密和数字签名\n\n需要生成密钥对(公钥和私钥)",
    "Caesar": "凯撒密码，古典替换密码\n\n通过字母位移实现加密",
    "Vigenere": "维吉尼亚密码，多表替换密码\n\n比凯撒密码更安全",
    "Base64": "Base64编码，不是加密算法\n\n用于二进制数据文本化表示",
    "Rail Fence": "栅栏密码，转置密码的一种\n\n通过改变字符排列顺序加密",
    "Morse": "摩尔斯电码，不是加密算法\n\n用于电报通信的字符编码",
    "ASCII": "ASCII编码，将字符转换为对应的十进制数值\n\n支持多种编码方式，可用于数据传输和存储，但不提供加密功能",
    "RC4": "流加密算法，简单高效\n\n但已被发现存在漏洞，不建议用于敏感数据"
}

HASH_DESCRIPTIONS = {
    "SHA-256": "安全哈希算法，生成256位哈希值",
    "SHA-512": "安全哈希算法，生成512位哈希值",
    "MD5": "消息摘要算法，生成128位哈希值\n\n已不推荐用于安全用途",
    "SHA3-256": "SHA-3算法，新一代安全哈希标准",
    "SHA3-512": "SHA-3算法，更长的哈希输出",
    "BLAKE2b": "高速哈希算法，比SHA-3更快\n\n常用于密码学和数据完整性校验"
}

def show_algorithm_info(algorithm, is_hash=False):
    """显示算法说明提示"""
    descriptions = HASH_DESCRIPTIONS if is_hash else ALGORITHM_DESCRIPTIONS
    description = descriptions.get(algorithm, "暂无该算法的详细说明")
    
    info_window = tk.Toplevel(root)
    info_window.title(f"{algorithm}算法说明")
    info_window.geometry("500x300")
    info_window.resizable(False, False)
    
    ttk.Label(info_window, text=f"{algorithm}算法说明", font=('Arial', 12, 'bold')).pack(pady=10)
    
    text_frame = ttk.Frame(info_window)
    text_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
    
    scrollbar = ttk.Scrollbar(text_frame)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    info_text = tk.Text(text_frame, wrap=tk.WORD, yscrollcommand=scrollbar.set,
                       bg=ModernTheme.TEXT_BG, fg=ModernTheme.FG_COLOR,
                       font=('Arial', 10), padx=5, pady=5)
    info_text.insert(tk.END, description)
    info_text.config(state=tk.DISABLED)
    info_text.pack(fill=tk.BOTH, expand=True)
    
    scrollbar.config(command=info_text.yview)
    
    ttk.Button(info_window, text="关闭", command=info_window.destroy).pack(pady=10)


# 功能: 密钥强度评估
def evaluate_key_strength(key, algorithm):
    """评估密钥强度并返回0-100的分数"""
    if not key:
        return 0
    
    length_score = 0
    complexity_score = 0
    
    # 长度评分
    key_len = len(key)
    if algorithm in ["AES", "DES", "3DES", "RC4"]:
        if algorithm == "AES":
            ideal_length = 32  # 256位
        elif algorithm == "DES":
            ideal_length = 8   # 64位(实际56位有效)
        elif algorithm == "3DES":
            ideal_length = 24  # 192位
        else:  # RC4
            ideal_length = 16  # 128位
        
        length_score = min(100, (key_len / ideal_length) * 100)
    elif algorithm in ["Caesar", "Rail Fence"]:
        try:
            shift = int(key)
            length_score = min(100, abs(shift) % 26 * 3.85)  # 26个字母
        except:
            length_score = 0
    elif algorithm == "Vigenere":
        length_score = min(100, key_len * 5)  # 每字符5分
    
    # 复杂度评分
    has_upper = any(c.isupper() for c in key)
    has_lower = any(c.islower() for c in key)
    has_digit = any(c.isdigit() for c in key)
    has_special = any(not c.isalnum() for c in key)
    
    complexity_factors = sum([has_upper, has_lower, has_digit, has_special])
    complexity_score = complexity_factors * 25  # 每个因素25分
    
    # 综合评分
    return min(100, (length_score * 0.6 + complexity_score * 0.4))

def create_scrolled_text(parent, height=10, width=70):
    """创建带滚动条的文本框"""
    frame = ttk.Frame(parent)
    
    text = tk.Text(frame, height=height, width=width,
                  bg=ModernTheme.ENTRY_BG, fg=ModernTheme.FG_COLOR,
                  font=('Consolas', 10),
                  highlightthickness=1,
                  highlightbackground=ModernTheme.ACCENT_COLOR,
                  highlightcolor=ModernTheme.ACCENT_COLOR)
    
    scrollbar = ttk.Scrollbar(frame, command=text.yview)
    text.configure(yscrollcommand=scrollbar.set)
    
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    
    return frame, text

def show_history():
    """显示操作历史记录窗口"""
    history = history_manager.get_history()
    
    history_window = tk.Toplevel(root)
    history_window.title("操作历史记录")
    history_window.geometry("800x500")
    
    # 添加图标，替换为实际图标文件路径
    try:
        history_window.wm_iconbitmap('C:/Users/10935/Desktop/大三/密码算法实训/大作业/Crypto_algor_system/历史记录.ico')
        print("历史记录界面图标加载成功")
    except tk.TclError as e:
        print(f"无法加载历史记录界面图标: {e}")

    # 标题
    ttk.Label(history_window, text="操作历史记录", font=('Arial', 12, 'bold')).pack(pady=10)
    
    # 历史记录表格
    tree_frame = ttk.Frame(history_window)
    tree_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
    
    scrollbar = ttk.Scrollbar(tree_frame)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    tree = ttk.Treeview(tree_frame, columns=("time", "operation", "algorithm", "input", "result"),
                        yscrollcommand=scrollbar.set, selectmode="browse")
    
    tree.heading("#0", text="ID")
    tree.heading("time", text="时间")
    tree.heading("operation", text="操作")
    tree.heading("algorithm", text="算法")
    tree.heading("input", text="输入(部分)")
    tree.heading("result", text="结果(部分)")
    
    tree.column("#0", width=40, stretch=tk.NO)
    tree.column("time", width=150, anchor=tk.W)
    tree.column("operation", width=80, anchor=tk.W)
    tree.column("algorithm", width=100, anchor=tk.W)
    tree.column("input", width=200, anchor=tk.W)
    tree.column("result", width=200, anchor=tk.W)
    
    for i, record in enumerate(reversed(history), 1):
        tree.insert("", tk.END, text=str(i),
                   values=(record["timestamp"], record["operation"], 
                          record["algorithm"], record["input"], record["result"]))
    
    tree.pack(fill=tk.BOTH, expand=True)
    scrollbar.config(command=tree.yview)
    
    # 操作按钮
    button_frame = ttk.Frame(history_window)
    button_frame.pack(pady=10)
    
    ttk.Button(button_frame, text="关闭", command=history_window.destroy).pack(side=tk.LEFT, padx=5)
    ttk.Button(button_frame, text="清空历史", command=clear_history).pack(side=tk.LEFT, padx=5)

def clear_history():
    """清空历史记录"""
    if messagebox.askyesno("确认", "确定要清空所有历史记录吗？"):
        history_manager.history = []
        history_manager.save_history()
        messagebox.showinfo("成功", "历史记录已清空")

def update_status(message):
    """更新状态栏消息"""
    status_var.set(message)
    root.update_idletasks()

def update_key_strength(*args):
    """更新密钥强度显示"""
    key = key_entry.get()
    algorithm = algorithm_var.get()
    
    if algorithm in ["AES", "DES", "3DES", "Caesar", "Vigenere", "Rail Fence", "RC4"]:
        strength = evaluate_key_strength(key, algorithm)
        key_strength_bar["value"] = strength
        
        if strength < 30:
            key_strength_bar["style"] = "red.Horizontal.TProgressbar"
        elif strength < 70:
            key_strength_bar["style"] = "yellow.Horizontal.TProgressbar"
        else:
            key_strength_bar["style"] = "green.Horizontal.TProgressbar"
        
        key_strength_label.config(text=f"密钥强度: {int(strength)}%")
    else:
        key_strength_bar["value"] = 0
        key_strength_label.config(text="密钥强度: N/A")

def create_tooltip(widget, text):
    """为控件创建工具提示"""
    tooltip = tk.Toplevel(root)
    tooltip.withdraw()
    tooltip.overrideredirect(True)
    
    label = ttk.Label(tooltip, text=text, background="#ffffe0", relief="solid", borderwidth=1)
    label.pack()
    
    def enter(event):
        x = widget.winfo_rootx() + widget.winfo_width() + 5
        y = widget.winfo_rooty()
        tooltip.geometry(f"+{x}+{y}")
        tooltip.deiconify()
    
    def leave(event):
        tooltip.withdraw()
    
    widget.bind("<Enter>", enter)
    widget.bind("<Leave>", leave)

# 添加暗黑模式切换
def toggle_dark_mode():
    if style.theme_use() == 'default':
        style.theme_use('alt')
        # 更新为暗色主题颜色
        ModernTheme.BG_COLOR = "#2d3436"
        ModernTheme.FG_COLOR = "#dfe6e9"
        # ... 更新其他颜色
    else:
        style.theme_use('default')
        # 恢复亮色主题

# =============================================
# 主程序入口
# =============================================
if __name__ == "__main__":
    # 创建主窗口
    root = tk.Tk()
    root.title("高级密码算法集成系统")
    root.geometry("900x700")
    root.configure(bg=ModernTheme.BG_COLOR)

     # 添加图标
    try:
        root.iconbitmap('C:/Users/10935/Desktop/大三/密码算法实训/大作业/Crypto_algor_system/图标.ico')  # 替换为图标文件路径
    except tk.TclError:
        print("无法加载图标文件，请检查路径是否正确。")      

   # 设置主题样式
    style = ttk.Style()
    style.theme_use('default')
    
    # 配置样式
    style.configure('TLabel', 
                   background=ModernTheme.LABEL_BG, 
                   foreground=ModernTheme.FG_COLOR,
                   font=('Arial', 10))
    
    style.configure('TButton', 
                   background=ModernTheme.BUTTON_BG, 
                   foreground=ModernTheme.BUTTON_FG,
                   font=('Arial', 10, 'bold'),
                   borderwidth=1,
                   focusthickness=3,
                   focuscolor='none')
    
    style.configure('Hover.TButton', 
                   background=ModernTheme.BUTTON_HOVER)
    
    style.configure('TCombobox',
                   fieldbackground=ModernTheme.ENTRY_BG,
                   selectbackground=ModernTheme.ACCENT_COLOR,
                   selectforeground='white')
    
    style.configure('TFrame',
                   background=ModernTheme.FRAME_BG)
    
    style.configure('TEntry',
                   fieldbackground=ModernTheme.ENTRY_BG)
    
    style.configure('green.Horizontal.TProgressbar',
                   background=ModernTheme.PROGRESS_FG,
                   troughcolor=ModernTheme.PROGRESS_BG)
    
    style.configure('yellow.Horizontal.TProgressbar',
                   background='#FFC107',
                   troughcolor=ModernTheme.PROGRESS_BG)
    
    style.configure('red.Horizontal.TProgressbar',
                   background='#F44336',
                   troughcolor=ModernTheme.PROGRESS_BG)
    
    style.map('TButton',
             background=[('active', ModernTheme.BUTTON_HOVER), 
                        ('disabled', '#cccccc')],
             foreground=[('disabled', '#888888')])

    # 主框架
    main_frame = ttk.Frame(root, padding="10")
    main_frame.pack(fill=tk.BOTH, expand=True)

    # 输入框架
    input_frame = ttk.Frame(main_frame)
    input_frame.pack(fill=tk.X, pady=5)

    # 明文/密文标签和输入框
    text_label = ttk.Label(input_frame, text="明/密文:", font=('Arial', 10, 'bold'))
    text_label.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)

     # 使用带滚动条的文本框
    text_frame, text_entry = create_scrolled_text(input_frame, height=8)
    text_frame.grid(row=1, column=0, columnspan=4, padx=5, pady=5, sticky="nsew")

    # 加载文件按钮
    load_button = ttk.Button(input_frame, text="📂 从文件读取", command=load_from_file)
    load_button.grid(row=1, column=4, padx=5, pady=5, sticky=tk.E)
    create_tooltip(load_button, "从文本文件加载内容")

    # 密钥框架
    key_frame = ttk.Frame(main_frame)
    key_frame.pack(fill=tk.X, pady=5)

    # 密钥标签和输入框
    key_label = ttk.Label(key_frame, text="密钥/位移量:", font=('Arial', 10, 'bold'))
    key_label.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)

    key_entry = ttk.Entry(key_frame, width=70, font=('Consolas', 10))
    key_entry.grid(row=0, column=1, padx=5, pady=5)
    key_entry.bind("<KeyRelease>", update_key_strength)

    # 密钥强度显示
    key_strength_label = ttk.Label(key_frame, text="密钥强度: N/A")
    key_strength_label.grid(row=1, column=1, sticky=tk.W, padx=5)

    key_strength_bar = ttk.Progressbar(key_frame, orient="horizontal", 
                                     length=200, mode="determinate",
                                     style="green.Horizontal.TProgressbar")
    key_strength_bar.grid(row=1, column=1, padx=5, pady=5, sticky=tk.E)

    # 算法选择框架
    algorithm_frame = ttk.Frame(main_frame)
    algorithm_frame.pack(fill=tk.X, pady=5)

    # 在界面中添加加载密钥按钮（RSA）
    load_private_button = ttk.Button(algorithm_frame, text="加载私钥", command=lambda: load_rsa_key(True))
    load_private_button.grid(row=0, column=6, padx=5, pady=5, sticky=tk.W)
    load_private_button.grid_remove()  # 初始隐藏
    create_tooltip(load_private_button, "从文件加载RSA私钥")


    load_public_button = ttk.Button(algorithm_frame, text="加载公钥", command=lambda: load_rsa_key(False))
    load_public_button.grid(row=0, column=7, padx=5, pady=5, sticky=tk.W)
    load_public_button.grid_remove()   # 初始隐藏
    create_tooltip(load_public_button, "从文件加载RSA公钥")

    # 算法选择标签和下拉菜单
    algorithm_label = ttk.Label(algorithm_frame, text="加密算法:", font=('Arial', 10, 'bold'))
    algorithm_label.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)

    algorithm_var = tk.StringVar()
    algorithm_menu = ttk.Combobox(algorithm_frame, textvariable=algorithm_var, 
                                 values=["AES", "DES", "3DES", "RSA", "Caesar", 
                                        "Vigenere", "Base64", "Rail Fence", 
                                        "Morse", "ASCII", "RC4"],
                                 font=('Arial', 10), width=15)
    algorithm_menu.current(0)
    algorithm_menu.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)
    algorithm_menu.bind("<<ComboboxSelected>>", on_algorithm_selected)
    create_tooltip(algorithm_menu, "选择加密/解密算法")

    # 算法信息按钮
    info_button = ttk.Button(algorithm_frame, text="ℹ️", width=2,
                           command=lambda: show_algorithm_info(algorithm_var.get()))
    info_button.grid(row=0, column=2, padx=2, pady=5, sticky=tk.W)
    create_tooltip(info_button, "查看算法说明")

    # 模式选择 (AES/DES/3DES)
    mode_label = ttk.Label(algorithm_frame, text="模式:", font=('Arial', 10, 'bold'))
    mode_label.grid(row=0, column=3, sticky=tk.W, padx=5, pady=5)

    mode_var = tk.StringVar()
    mode_menu = ttk.Combobox(algorithm_frame, textvariable=mode_var, 
                            values=["ECB", "CBC"], font=('Arial', 10), width=5)
    mode_menu.current(0)
    mode_menu.grid(row=0, column=4, padx=5, pady=5, sticky=tk.W)

    # RSA密钥生成按钮
    generate_rsa_button = ttk.Button(algorithm_frame, text="生成RSA密钥对", command=generate_rsa_key_pair)
    generate_rsa_button.grid(row=0, column=5, padx=5, pady=5, sticky=tk.W)
    generate_rsa_button.grid_remove()  # 初始隐藏
    create_tooltip(generate_rsa_button, "生成新的RSA密钥对")

    # 哈希算法选择框架
    hash_frame = ttk.Frame(main_frame)
    hash_frame.pack(fill=tk.X, pady=5)

    hash_label = ttk.Label(hash_frame, text="哈希算法:", font=('Arial', 10, 'bold'))
    hash_label.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)

    hash_algorithm_var = tk.StringVar()
    hash_menu = ttk.Combobox(hash_frame, textvariable=hash_algorithm_var,
                            values=["SHA-256", "SHA-512", "MD5", "SHA3-256", "SHA3-512", "BLAKE2b"],
                            font=('Arial', 10), width=10)
    hash_menu.current(0)
    hash_menu.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)
    create_tooltip(hash_menu, "选择哈希算法")

    # 哈希算法信息按钮
    hash_info_button = ttk.Button(hash_frame, text="ℹ️", width=2,
                                command=lambda: show_algorithm_info(hash_algorithm_var.get(), True))
    hash_info_button.grid(row=0, column=2, padx=2, pady=5, sticky=tk.W)
    create_tooltip(hash_info_button, "查看哈希算法说明")

    # 按钮框架
    button_frame = ttk.Frame(main_frame)
    button_frame.pack(fill=tk.X, pady=10)

    # 历史记录按钮
    history_button = ttk.Button(button_frame, text="📜 历史记录", command=show_history)
    history_button.grid(row=0, column=0, padx=5)   # 放在第一个位置
    create_tooltip(history_button, "查看操作历史记录")

    # 在button_frame中添加验证按钮（RSA）
    verify_button = ttk.Button(button_frame, text="✓ 验证签名", command=verify_signature)
    verify_button.grid(row=0, column=1, padx=5)    # 放在第二个位置
    verify_button.grid_remove()  # 初始隐藏
    create_tooltip(verify_button, "验证RSA签名")

    # 加密按钮
    encrypt_button = ttk.Button(button_frame, text="🔒 加密", command=encrypt_text)
    encrypt_button.grid(row=0, column=2, padx=5)    # 放在第三个位置
    create_tooltip(encrypt_button, "执行加密操作 (Ctrl+E)")

    # 解密按钮
    decrypt_button = ttk.Button(button_frame, text="🔓 解密", command=decrypt_text)
    decrypt_button.grid(row=0, column=3, padx=5)   # 放在第四个位置
    create_tooltip(decrypt_button, "执行解密操作 (Ctrl+D)")

    # 哈希按钮
    hash_button = ttk.Button(button_frame, text="🔢计算哈希", command=compute_hash_text)
    hash_button.grid(row=0, column=4, padx=5)      # 放在第五个位置
    create_tooltip(hash_button, "计算哈希值 (Ctrl+H)")

    # 清空按钮
    clear_button = ttk.Button(button_frame, text="🗑️ 清空", command=clear_text)
    clear_button.grid(row=0, column=5, padx=5)
    create_tooltip(clear_button, "清空所有输入 (Ctrl+Shift+C)")

    # 结果框架
    result_frame = ttk.Frame(main_frame)
    result_frame.pack(fill=tk.BOTH, expand=True, pady=5)

    # 配置列的权重
    result_frame.grid_columnconfigure(0, weight=1)  # 文本框列
    result_frame.grid_columnconfigure(1, weight=0)  # 操作按钮列

    # 结果标签和输出框
    result_label = ttk.Label(result_frame, text="结果:", font=('Arial', 10, 'bold'))
    result_label.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)

    # 使用带滚动条的结果文本框
    result_text_frame, result_text = create_scrolled_text(result_frame, height=10)
    result_text_frame.grid(row=1, column=0, columnspan=3, padx=5, pady=5, sticky="nsew")

    # 操作按钮框架
    action_frame = ttk.Frame(result_frame)
    action_frame.grid(row=1, column=3, padx=5, pady=5, sticky=tk.NS)

    # 复制按钮
    copy_button = ttk.Button(action_frame, text="📋 复制", command=copy_result)
    copy_button.pack(pady=5)
    create_tooltip(copy_button, "复制结果到剪贴板 (Ctrl+C)")

    # 保存按钮
    save_button = ttk.Button(action_frame, text="💾 保存", command=save_to_file)
    save_button.pack(pady=5)
    create_tooltip(save_button, "保存结果到文件 (Ctrl+S)")

    # 添加悬停效果
    for button in [encrypt_button, decrypt_button, hash_button, clear_button, copy_button, save_button, load_button]:
        button.bind("<Enter>", on_enter)
        button.bind("<Leave>", on_leave)

    # 签名标签
    signature_label = ttk.Label(result_frame, text="", font=('Arial', 9))
    signature_label.grid(row=2, column=0, columnspan=4, sticky=tk.W, padx=5, pady=5)
    signature_label.bind("<Button-3>", show_context_menu)  # 右键点击

    # 状态栏
    status_var = tk.StringVar()
    status_var.set("准备就绪")
    
    status_bar = ttk.Label(root, textvariable=status_var, relief=tk.SUNKEN, anchor=tk.W,
                          background=ModernTheme.STATUS_BAR_BG, 
                          foreground=ModernTheme.STATUS_BAR_FG,
                          font=('Arial', 9, 'bold'))
    status_bar.pack(side=tk.BOTTOM, fill=tk.X)

    # 添加切换按钮
    dark_mode_button = ttk.Button(root, text="🌓", command=toggle_dark_mode)
    dark_mode_button.pack(anchor=tk.SE, padx=10, pady=5)  # 使用SE锚点并调整填充

    # 在主窗口配置中添加底部边框效果
    bottom_border = tk.Frame(root, height=3, bg=ModernTheme.BOTTOM_ACCENT)
    bottom_border.pack(side=tk.BOTTOM, fill=tk.X, before=status_bar)

    # 添加快捷键支持
    root.bind("<Control-e>", lambda e: encrypt_text())
    root.bind("<Control-d>", lambda e: decrypt_text())
    root.bind("<Control-h>", lambda e: compute_hash_text())
    root.bind("<Control-s>", lambda e: save_to_file())
    root.bind("<Control-c>", lambda e: copy_result())
    root.bind("<Control-Shift-C>", lambda e: clear_text())

    # 为所有按钮添加悬停效果
    for button in [encrypt_button, decrypt_button, hash_button, clear_button, 
                  copy_button, save_button, load_button, history_button,
                  generate_rsa_button, load_private_button, load_public_button,
                  verify_button, info_button, hash_info_button]:
        button.bind("<Enter>", on_enter)
        button.bind("<Leave>", on_leave)

    # 运行主循环
    root.mainloop()